package com.sec.etech.sys.cal.service;

import cn.hutool.core.date.CalendarUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import org.openbpm.sys.api.model.calendar.WorkCalendar;
import org.openbpm.sys.core.manager.HolidayConfManager;
import org.openbpm.sys.core.manager.WorkCalendarManager;
import org.openbpm.sys.core.manager.impl.WorkCalendarManagerImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Etech定制工作日服务
 */
@Service
public class WorkCalService extends WorkCalendarManagerImpl implements WorkCalendarManager{

    @Resource
    HolidayConfManager holidayConfManager;
    @Resource
    WorkCalendarManager workCalenDarManager;


    /**
     * 获取n个工作日后的工作日期：n可以为负值
     */
    public Date getWorkDayByDay(Date startDay, int days) {
        Date date = null;
        if(days>0){
            date = this.getWorkDayByDays(startDay, days);
        }else{
            date = this.getPreviousWorkDay(startDay, days);
        }
        return date;
    }
    /**
     * 获取n个工作日后的工作日期：n可以为负值
     */
    public Date getWorkDayByDay(Date startDay, int days, int months) {
        Date date = null;
        if(days>0){
            date = this.getWorkDayByDays(startDay, days);
        }else{
            date = this.getPreviousWorkDay(startDay, days, months);
        }
        return date;
    }
    /**
     * 获取开始时间结束时间之内的工作日天数
     * 修改当天为0天
     */
    public int getWorkDaysByTime4remainDay(Date startDay, Date endDay) {
        int days = getWorkDaysByTime(startDay, endDay);
        if(days>0){
            days --;
        }else if(days<0){
            days ++;
        }
        return days;
    }

    public int getWorkDaysByTime(Date startDay, Date endDay) {
        int days = 1;
        int count = 0;
        Date day1 = startDay;
        Date day2 = endDay;
        if(startDay.after(endDay)){
            day1 = endDay;
            day2 = startDay;
            days = -1;
        }
        List<WorkCalendar> darList = this.getByTime(day1, day2);
        for(WorkCalendar day: darList){
            if(day.isWorkDay()){
                count++;
            }
        }
        return days*count;
    }
    //判断是否工作日
    public boolean isWorkDay(Date today){
        boolean flag = false;
        List<WorkCalendar> darList = this.getByTime(today);
        if(darList!=null && darList.size()>0) {
            for(WorkCalendar day: darList) {
                if(day.isWorkDay()){
                    flag = true;
                }else{
                    flag = false;
                    break;
                }
            }
        }
        return flag;
    }
    //获取下一个工作日(最多15个自然日）
    public Date nextWorkDay(Date day1){
        Calendar cal = CalendarUtil.calendar(day1);
        int cc = 0;
        while(true){
            if(isWorkDay(cal.getTime())){
                break;
            }
            cal.add(Calendar.DAY_OF_MONTH, 1);
            cc++;
            if(cc>15){
                break;
            }
        }
        return cal.getTime();
    }

    //根据日期计算days之前的工作日期 ：D-n  n天前的工作日期
    private Date getPreviousWorkDay(Date startDay, int days){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDay);
        int month = days/20 + 1;  //预估月份
        calendar.add(Calendar.MONTH, -month);//提前
        Date preDay = calendar.getTime();
        int num = this.getWorkDaysByTime(preDay, startDay);
        return this.getWorkDayByDays(preDay, num + days - 1);
    }
    //根据日期计算days之前的工作日期 ：D-n  n天前的工作日期，提前月数参数传入
    private Date getPreviousWorkDay(Date startDay, int days, int months){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDay);
        int monthTmp = days/20 + months;  //预估月份
        calendar.add(Calendar.MONTH, -monthTmp);//提前
        Date preDay = calendar.getTime();
        int num = this.getWorkDaysByTime(preDay, startDay);
        return this.getWorkDayByDays(preDay, num + days - 1);
    }

    //计算months月之前，days日之后的的工作日期（days>0），月份不换算为天数
    public Date getPreviousMonthsWorkDay(Date startDay, int days, int months){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDay);
        calendar.add(Calendar.MONTH, -months);//提前
        Date preDay = calendar.getTime();
        return this.getWorkDayByDays(preDay, days);
    }

    public static Date beginOfDay(Date day){
        return DateUtil.beginOfDay(day);
    }
    public static Date endOfDay(Date day){
        Calendar cal = Calendar.getInstance();
        cal.setTime(day);
        cal = DateUtil.endOfDay(cal);
        cal = DateUtil.truncate(cal, DateField.SECOND);
        return cal.getTime();
    }
}
